package com.teamtgv.shareshark;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.util.Log;

import com.teamtgv.shareshark.task.UpdateImageUrlTask;

public class ImageShack {

	public static final String LOG_TAG = ShareActivity.class.getSimpleName();
	private String API_KEY = "02FHMORX0e6e27054ad20890adfd182653fb30bb";

	public ImageShack() {
	}

	public Bitmap download(Context context, final String imageUrl) {
		Log.v(LOG_TAG, "Downloading image from " + imageUrl);

		final ExecutorService service = Executors.newFixedThreadPool(1); 
        final Future<Bitmap>  task = service.submit(new DownloadThread(imageUrl));

        Bitmap downloadedBitmap = null;
        try {
			downloadedBitmap = task.get();
		} catch (Exception e) {
			Log.e(LOG_TAG, "Error executing download task: " + imageUrl
					+ " --> " + e.toString() + ": " + e.getMessage());
		}
        if (downloadedBitmap == null)
        	Log.v(LOG_TAG, "Downloaded image is null");
        service.shutdownNow();
        return downloadedBitmap;
	}
	
	private class DownloadThread implements Callable<Bitmap> {
		
		private String imageUrl;
		
		public DownloadThread(String imageUrl) {
			this.imageUrl = imageUrl;
		}

		@Override
		public Bitmap call() throws Exception {
			try {
				URL url = new URL(imageUrl);
				HttpURLConnection connection = (HttpURLConnection) url
						.openConnection();
				connection.setDoInput(true);
				connection.connect();
				InputStream input = connection.getInputStream();
				Bitmap downloadedBitmap = BitmapFactory.decodeStream(input);
				Log.v(LOG_TAG, "Image downloaded");
				return downloadedBitmap;
			} catch (IOException e) {
				Log.e(LOG_TAG, "Error downloading image from " + imageUrl
						+ " --> " + e.toString() + ": " + e.getMessage());
				return null;
			}
		}
	}

	public void upload(final Bitmap bitmap, final int recordId) {
		Log.v(LOG_TAG, "Initiating upload");

		final Thread d = new Thread(new Runnable() {
			@Override
			public void run() {

				String upLoadServerUri = " http://www.imageshack.us/upload_api.php";

				HttpURLConnection conn = null;
				DataOutputStream dos = null;
				String lineEnd = "\r\n";
				String twoHyphens = "--";
				String boundary = "*****";
				int bytesRead, bytesAvailable, bufferSize;
				byte[] buffer;
				int maxBufferSize = 1 * 1024 * 1024;

				try { // open a URL connection to the Servlet
					ByteArrayOutputStream bos = new ByteArrayOutputStream();
					bitmap.compress(CompressFormat.JPEG,
							100 /* ignored for PNG */, bos);
					byte[] bitmapdata = bos.toByteArray();
					ByteArrayInputStream bs = new ByteArrayInputStream(
							bitmapdata);
					URL url = new URL(upLoadServerUri);
					conn = (HttpURLConnection) url.openConnection(); // Open a
																		// HTTP
																		// connection
																		// to
																		// the
																		// URL
					conn.setDoInput(true); // Allow Inputs
					conn.setDoOutput(true); // Allow Outputs
					conn.setUseCaches(false); // Don't use a Cached Copy
					conn.setRequestMethod("POST");
					conn.setRequestProperty("Connection", "Keep-Alive");
					// conn.setRequestProperty("ENCTYPE",
					// "multipart/form-data");
					conn.setRequestProperty("Content-Type",
							"multipart/form-data;boundary=" + boundary);
					conn.setRequestProperty("uploaded_file", "bitmap");

					dos = new DataOutputStream(conn.getOutputStream());
					dos.writeBytes(twoHyphens + boundary + lineEnd);
					// ///////////////////////////////////////////////////////////////////

					dos.writeBytes("Content-Disposition: form-data; name=\"key\""
							+ lineEnd);
					dos.writeBytes(lineEnd);
					dos.writeBytes(API_KEY);
					dos.writeBytes(lineEnd);
					dos.writeBytes(twoHyphens + boundary + lineEnd);

					// for image
					dos.writeBytes("Content-Disposition: form-data; name=\"fileupload\";filename=\""
							+ "bitmap" + "\"" + lineEnd);
					dos.writeBytes("Content-Type: image/jpeg" + lineEnd);
					dos.writeBytes("Content-Transfer-Encoding: binary"
							+ lineEnd);
					dos.writeBytes(lineEnd);
					// dos.writeBytes(twoHyphens + boundary + lineEnd);

					bytesAvailable = bs.available();

					bufferSize = Math.min(bytesAvailable, maxBufferSize);
					buffer = new byte[bufferSize];

					// read file and write it into form...
					bytesRead = bs.read(buffer, 0, bufferSize);

					while (bytesRead > 0) {
						dos.write(buffer, 0, bufferSize);
						bytesAvailable = bs.available();
						bufferSize = Math.min(bytesAvailable, maxBufferSize);
						bytesRead = bs.read(buffer, 0, bufferSize);
					}

					// send multipart form data necesssary after file data...
					dos.writeBytes(lineEnd);
					dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

					Log.v(LOG_TAG, "Upload completed");

					// Responses from the server (code and message)
					int serverResponseCode = conn.getResponseCode();
					String serverResponseMessage = conn.getResponseMessage();
					InputStream servere = conn.getInputStream();

					String response = serverResponseCode + ": "
							+ serverResponseMessage + ". ";

					byte[] responseBuffer = new byte[1024];

					while (servere.read(responseBuffer) >= 0) {
						response += new String(responseBuffer);
					}

					// ! parse on <image_link>
					Log.v("ImageShack", "Response from server obtained: " + response.substring(0, 100) + "...");

					// close the streams //
					bs.close();
					dos.flush();
					dos.close();

					Pattern p = Pattern
							.compile("<image_link>(.*?)</image_link>");
					Matcher m = p.matcher(response);
					if (m.find()) {
						String imageUrl = m.group(1);
						UpdateImageUrlTask updateUrlTask = new UpdateImageUrlTask(recordId);
						updateUrlTask.execute(imageUrl);
						Log.v(LOG_TAG, "Set image url in result: " + imageUrl);
					}

				} catch (Exception e) {
					Log.e(LOG_TAG,
							"Exception occured during uploading: "
									+ e.toString() + " - " + e.getMessage());
				}

			}
		});

		d.start();

	}
	
}
